﻿using Microsoft.Extensions.Logging;
using SqlSugar; 
using TianYu.Core.Common;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionExtensions
    {
        //*************************************************************
        //  appsettings.json 配置示例：
        //
        // "SqlSugar": {
        //    "DbType": "MySql",
        //    "EnabledLog": true,
        //    "ConnectionString": "server=127.0.0.1;port=3306;user id=test;password=test;database=test;CharSet=utf8mb4;allow zero datetime=true;Convert Zero Datetime=true;"
        // },
        //
        //************************************************************* 
        public static IServiceCollection AddSqlSugarSetup(this IServiceCollection services)
        {
            var connectionString = AppsettingsHelper.AppRequired(new string[] { "SqlSugar", "ConnectionString" });
            var enabledLog = AppsettingsHelper.App(new string[] { "SqlSugar", "EnabledLog" }).ObjToBool();
            services.AddSingleton<ISqlSugarClient>(o =>
            {
                var logger = o.GetService(typeof(ILogger<ISqlSugarClient>)) as ILogger;
                var config = new ConnectionConfig()
                {
                    ConnectionString = connectionString,
                    DbType = GetDbType(),
                    IsAutoCloseConnection = true,
                    LanguageType = LanguageType.Chinese,
                    MoreSettings = new ConnMoreSettings
                    {
                        IsAutoRemoveDataCache = true
                    }
                };

                if (enabledLog)
                {
                    string GetParas(SugarParameter[] pars)
                    {
                        string key = "【SQL参数】：";
                        foreach (var param in pars)
                        {
                            key += $"{param.ParameterName}:{param.Value}\n";
                        }
                        return key;
                    }
                    string GetSqlLog(string sql, SugarParameter[] pars)
                    {
                        return $"【SQL语句】：{sql}\n{GetParas(pars)}";
                    }
                    config.AopEvents = new AopEvents
                    {
                        OnLogExecuting = (sql, p) =>
                        {
                            logger.LogInformation(GetSqlLog(sql, p));
                        },
                        OnError = (ex) =>
                        {
                            logger.LogError($"【SQL报错】：{ex.Message}\n{GetSqlLog(ex.Sql, ex.Parametres as SugarParameter[])}");
                        }
                    };
                }
                return new SqlSugarScope(config);
            });
            return services;
        }

        private static DbType GetDbType()
        {
            var dbType = AppsettingsHelper.AppRequired(new string[] { "SqlSugar", "DbType" });

            dbType = dbType.ToLower();

            switch (dbType)
            {
                case "mysql": return DbType.MySql;
                case "sqlserver": return DbType.SqlServer;
                case "sqlite": return DbType.Sqlite;
                case "oracle": return DbType.Oracle;
                case "postgresql": return DbType.PostgreSQL;
                case "dm": return DbType.Dm;
                case "kdbndp": return DbType.Kdbndp;
                case "oscar": return DbType.Oscar;
                case "access": return DbType.Access;
                case "opengauss": return DbType.OpenGauss;
                case "questdb": return DbType.QuestDB;
                case "hg": return DbType.HG;
                case "clickhouse": return DbType.ClickHouse;
                case "gbase": return DbType.GBase;
                case "odbc": return DbType.Odbc;
                case "custom": return DbType.Custom;
            }

            throw new Exception($"无效的数据库类型:{dbType}");
        }
    }
}